package org.esgl3d.ui;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import javax.microedition.khronos.opengles.GL10;

import org.esgl3d.rendering.Texture;
import org.esgl3d.rendering.VertexContainer;
import org.omg.CORBA.PRIVATE_MEMBER;

import android.graphics.Bitmap;

public class BitmapFont {
	Texture fontTexture;

	FloatBuffer fontTex;
	FloatBuffer face;
	
	public BitmapFont(Texture texture) {
		fontTexture = texture;

		float width = 1f/16f;
		float height = width;

		float[] fontTexCoords = new float[16*16*8];
		int ix = 0;
		for (int row = 0; row < 16; ++row) {
			for(int col = 0; col < 16; ++col) {				
				fontTexCoords[ix++] = col*width;
				fontTexCoords[ix++] = row*height + 0.01f;

				fontTexCoords[ix++] = col*width;
				fontTexCoords[ix++] = (row+1)*height - 0.01f;

				fontTexCoords[ix++] = (col+1)*width;
				fontTexCoords[ix++] = (row)*height + 0.01f;

				fontTexCoords[ix++] = (col+1)*width;
				fontTexCoords[ix++] = (row+1)*height - 0.01f;
			}
		}
		fontTex = makeFloatBuffer(fontTexCoords);
		
		float faceVerts[] = new float[] {
				-0.5f, -0.5f,  0.5f,
				-0.5f,  0.5f,  0.5f,
				0.5f, -0.5f,  0.5f,
				0.5f,  0.5f,  0.5f,
		};
		face = makeFloatBuffer(faceVerts);
	}
	
	public void bindTexture(GL10 gl) {
		fontTexture.bind(gl);
	}
	
	

	public void drawInBuffers(VertexContainer container, char[] chars) {
		
		
		for (int i = 0; i< chars.length; ++i) {
			// draw two triangles for each char
			// 0-2    2
			// |/    /|
			// 1    0-1
			
			//vertices.put(i);
			//vertices.put(0);
			container.setPosition(i*6+0, i,0);
			
			
			//vertices.put(i);
			//vertices.put(1);
			container.setPosition(i*6+1, i, 1);
			
			//vertices.put(i+1);
			//vertices.put(0);
			container.setPosition(i*6+2, i+1, 0);
			
			//vertices.put(i);
			//vertices.put(1);
			container.setPosition(i*6+3,i,1);
			
			//vertices.put(i+1);
			//vertices.put(1);
			container.setPosition(i*6+4,i+1,1);
			
			//vertices.put(i+1);
			//vertices.put(0);
			container.setPosition(i*6+5, i+1,0);
			
			fontTex.position(chars[i]*8);
			//texture.put(fontTex.get());
			//texture.put(fontTex.get());
			container.setTexture(i*6+0, fontTex.get(),fontTex.get());
			
			//texture.put(fontTex.get());
			//texture.put(fontTex.get());
			container.setTexture(i*6+1, fontTex.get(),fontTex.get());
			
			//texture.put(fontTex.get());
			//texture.put(fontTex.get());
			container.setTexture(i*6+2, fontTex.get(),fontTex.get());
			
			fontTex.position(chars[i]*8+2);
			//texture.put(fontTex.get());
			//texture.put(fontTex.get());
			container.setTexture(i*6+3, fontTex.get(),fontTex.get());
			fontTex.position(chars[i]*8+6);
			//texture.put(fontTex.get());
			//texture.put(fontTex.get());
			container.setTexture(i*6+4, fontTex.get(),fontTex.get());
			fontTex.position(chars[i]*8+4);
			//texture.put(fontTex.get());
			//texture.put(fontTex.get());
			container.setTexture(i*6+5, fontTex.get(),fontTex.get());
			
			
		}
	}

	/**
	 * Make a direct NIO FloatBuffer from an array of floats
	 * @param arr The array
	 * @return The newly created FloatBuffer
	 */
	protected static FloatBuffer makeFloatBuffer(float[] arr) {
		ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
		bb.order(ByteOrder.nativeOrder());
		FloatBuffer fb = bb.asFloatBuffer();
		fb.put(arr);
		fb.position(0);
		return fb;
	}

	/**
	 * Make a direct NIO IntBuffer from an array of ints
	 * @param arr The array
	 * @return The newly created IntBuffer
	 */
	protected static IntBuffer makeFloatBuffer(int[] arr) {
		ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
		bb.order(ByteOrder.nativeOrder());
		IntBuffer ib = bb.asIntBuffer();
		ib.put(arr);
		ib.position(0);
		return ib;
	}
	
	protected static ByteBuffer makeByteBuffer(Bitmap bmp) {
		ByteBuffer bb = ByteBuffer.allocateDirect(bmp.getHeight()*bmp.getWidth()*4);
		bb.order(ByteOrder.BIG_ENDIAN);
		IntBuffer ib = bb.asIntBuffer();

		for (int y = 0; y < bmp.getHeight(); y++)
			for (int x=0;x<bmp.getWidth();x++) {
				int pix = bmp.getPixel(x, bmp.getHeight()-y-1);
				// Convert ARGB -> RGBA
				byte alpha = (byte)((pix >> 24)&0xFF);
				byte red = (byte)((pix >> 16)&0xFF);
				byte green = (byte)((pix >> 8)&0xFF);
				byte blue = (byte)((pix)&0xFF);
								
				ib.put(((red&0xFF) << 24) | 
					   ((green&0xFF) << 16) |
					   ((blue&0xFF) << 8) |
					   ((alpha&0xFF)));
			}
		ib.position(0);
		bb.position(0);
		return bb;
	}
}